﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Fakes;
using Microsoft.Xrm.Sdk.Messages;
using System.Fakes;
using Microsoft.Xrm.Sdk.Query;
using Xrm.Solutions.FrameworkSample.Plugins;

namespace Xrm.Solutions.FrameworkSample.UnitTests
{
    [TestClass]
    public class TestAutoNumberUsingStubs
    {
        private ParameterCollection inputParameters;
        private string _prefix = "TestPrefix";
        
        [TestMethod]
        public void TestReferenceIsGenerated()
        {
            #region Setup

            //IOrganizationService Stub
            
            StubIOrganizationService serviceStub = new StubIOrganizationService();
            serviceStub.RetrieveMultipleQueryBase = (query) =>
            {
                EntityCollection entities = new EntityCollection();

                if (query is QueryByAttribute)
                {
                    Entity config = new Entity("xdft_configuration");
                    config["xdft_value"] = _prefix;
                    entities.Entities.Add(config);
                }
                return entities;
            };

            //IOrganizationServiceFactory Stub
            
            StubIOrganizationServiceFactory factoryStub = new StubIOrganizationServiceFactory();
            factoryStub.CreateOrganizationServiceNullableOfGuid = (id) =>
            {
                return serviceStub;
            };

            StubITracingService tracingStub = new StubITracingService();

            //IPluginExecutionContext Stub
            
            StubIPluginExecutionContext contextStub = new StubIPluginExecutionContext();
            contextStub.PrimaryEntityNameGet = () => { return "account"; };
            contextStub.MessageNameGet = () => { return "Create"; };
            contextStub.StageGet = () => { return 20; };

            //Set Target
            contextStub.InputParametersGet = () =>
            {
                if (this.inputParameters == null)
                {
                    this.inputParameters = new ParameterCollection();
                    this.inputParameters["Target"] = new Entity("account");
                }
                return this.inputParameters;
            };

            //IServiceProvider Stub
            StubIServiceProvider stubServiceProvider = new StubIServiceProvider();
            stubServiceProvider.GetServiceType = (type) =>
            {
                if (type == typeof(ITracingService))
                    return tracingStub;
                else if (type == typeof(IOrganizationServiceFactory))
                    return factoryStub;
                else if (type == typeof(IPluginExecutionContext))
                    return contextStub;
                else
                    return null;
            };

            #endregion

            #region Test

            PreAccountCreate plugin = new PreAccountCreate();

            plugin.Execute(stubServiceProvider);

            #endregion

            #region Verify

            Entity modifiedTarget = (Entity)this.inputParameters["Target"];

            string reference = modifiedTarget["xdft_reference"].ToString();

            Assert.IsTrue(reference.Contains(_prefix));

            #endregion
        }
    }
}
